package analiseSintatica.Regras.Comandos;

import AnaliseLexicaFinal.EstruturaDeDados.LinkToken;
import analiseSemantica.ErroSemantico;
import analiseSemantica.Tipos.TipoSemantico;
import analiseSemantica.Tipos.TiposSemanticos;
import analiseSintatica.AnalisadorSintatico;
import analiseSintatica.ErroSintaticoException;
import analiseSintatica.Regras.*;
import analiseSintatica.Regras.Expressoes.RegraExpressao;
import analiseSintatica.Regras.Expressoes.RegraIncremento;

import analiseSintatica.Regras.Expressoes.RegraAtribuicao;



import java.util.LinkedList;

/**
 *
 * @author Ivo Romário
 * 
 */
public class RegraFor extends Regra{
    
    protected String estrutura = "for '(' <atribuicao> ';' <expressao> ';' <incremento> ')' <bloco>";

    protected static Regra instancia;




    /**
     * Construtor privado necessario ao singleton
     */
    private RegraFor() {
    }

    /**
     * Retorna a unica instancia dessa classe.
     * @return
     */
    public static RegraFor getInstance() {
        if (instancia == null) {
            instancia = new RegraFor();
        }
        return (RegraFor) instancia;
    }

   
    

    @Override
    public TiposSemanticos analisar(LinkedList<LinkToken> listaTokens) throws ErroSintaticoException {
    	
    	listaTokens.removeFirst();
    	
    	reconheceLexema(listaTokens, "delimitador", "(", estrutura);
        
    	TiposSemanticos tipoatribuicao = RegraAtribuicao.getInstance().analisar(listaTokens);
    	if(tipoatribuicao != null){
    		TipoSemantico tipoatrib = tipoatribuicao.removeTipos();
	    	String tipoatrib2 = (String)tipoatrib.getTipo();
	    	if(!tipoatrib2.toLowerCase().equals("int")){
	    		AnalisadorSintatico.errosemanticos.add(new ErroSemantico("Atribuicao deve ter valor inteiro para o comando for", tipoatrib.getLinha()));
	    	}
    	}
    	       
    	reconheceLexema(listaTokens, "delimitador", ";", estrutura);
    	
    	TiposSemanticos tipoexpressao = RegraExpressao.getInstance().analisar(listaTokens);
        if(tipoexpressao != null){
	        TipoSemantico tipoexpr = tipoexpressao.removeTipos();
	        String tipoexp = (String)tipoexpr.getTipo();
	        if(!tipoexp.toLowerCase().equals("boolean")){
	        	AnalisadorSintatico.errosemanticos.add(new ErroSemantico("Expressao deve ter valor booleano", tipoexpr.getLinha()));
	        }
        }

    	reconheceLexema(listaTokens, "delimitador", ";", estrutura);

    	RegraIncremento.getInstance().analisar(listaTokens);
        
        reconheceLexema(listaTokens, "delimitador", ")", estrutura);

        TiposSemanticos tipos = RegraBloco.getInstance().analisar(listaTokens);
        
        return tipos;
    }
    
    protected void setPrimeiro() {
        this.primeiro.add("for");
    }
}